﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sharp3D.Math.Core;
using ReAnimation.Helpers.Common;

namespace GLWrap.SceneObjects.Line
{
    public class DottedLine: BaseLine
    {
        private readonly float DEFAULT_RADIUS = 0.05f;
        private readonly float DEFAULT_FILL_PERCENT = 100;
        private float _fillPercent;
        private int _dotsCount;
        private IList<Sphere> _spheres;

        public override float Weight
        {
            get
            {
                return base.Weight;
            }
            set
            {
                base.Weight = value;
                _spheres.ForEach(sphere => { sphere.Radius = value; });
            }
        }

        /// <summary>
        /// Filled part of line in percents
        /// </summary>
        public float FillPercent 
        {
            get
            {
                return _fillPercent;
            }
            set
            {
                if (value < 1 || value > 100)
                    throw new ArgumentOutOfRangeException("FillPercent","Must be between 1 and 100");

                _fillPercent = value;

                MarkAsDirty();
            }
        }

        public int DotsCount 
        {
            get
            {
                return _dotsCount;
            }

            private set
            {
                ValidateDotsCount(value);
                _dotsCount = value;
            }
        }

        public DottedLine(int dotsCount)
        {
            ValidateDotsCount(dotsCount);
            _spheres = new List<Sphere>();
            DotsCount = dotsCount;
            DotsCount.TimesDo((i) => _spheres.Add(new Sphere()));
            AttachObjects(_spheres.Cast<SceneObject>());
            Weight = DEFAULT_RADIUS;
            FillPercent = DEFAULT_FILL_PERCENT;
        }

        private void ValidateDotsCount(int dotsCount)
        {
            if (dotsCount < 2) 
                throw new ArgumentOutOfRangeException("dotsCount", "Must be >= 2");
        }

        protected override void InternalRecalculateLineForSceneManager(GlSceneManager sceneManager)
        {
            Vector3F fullLine = PointB - PointA;
            Vector3F moveLine = fullLine/(DotsCount - 1)*_fillPercent/100.0f;
            Vector3F offsetLine = fullLine * (100 - _fillPercent) / 100.0f / 2.0f;

            DotsCount.TimesDo((i) => { _spheres[i].Position = PointA + offsetLine + moveLine * i; });

            MarkAsClean();
        }
    }
}
